package com.zjsru.plan2025.oneday;

import java.util.*;

/**
 * 3305. 元音辅音字符串计数 I
 *
 * @Author: cookLee
 * @Date: 2025-03-12
 */
public class CountOfSubstrings {

    /**
     * 主
     * \
     * 输入：word = "aeioqq", k = 1
     * 输出：0
     * 解释：
     * 不存在包含所有元音字母的子字符串。
     * \
     * 输入：word = "aeiou", k = 0
     * 输出：1
     * 解释：
     * 唯一一个包含所有元音字母且不含辅音字母的子字符串是 word[0..4]，即 "aeiou"。
     * \
     *
     * @param args args
     */
    public static void main(String[] args) {
        CountOfSubstrings countOfSubstrings = new CountOfSubstrings();
        String word = "aeioqq";
        int k = 1;
        System.out.println(countOfSubstrings.countOfSubstrings(word, k));
    }

    private final List<Character> vowel = Arrays.asList('a', 'e', 'i', 'o', 'u');

    public int countOfSubstrings(String word, int k) {
        int len = word.length();
        int ans = 0;
        for (int i = 0; i < len; i++) {
            Set<Character> set = new HashSet<>();
            //辅音数量
            int count = 0;
            for (int j = i; j < len; j++) {
                if (this.vowel.contains(word.charAt(j))) {
                    set.add(word.charAt(j));
                } else {
                    count++;
                }
                if (set.size() == 5 && count == k) {
                    ans++;
                }
            }
        }
        return ans;
    }

    /**
     * 滑动窗口
     *
     * @param word 字
     * @param k    k
     * @return int
     */
    public long countOfSubstrings2(String word, int k) {
        /**
         * helper(word, k) 计算包含所有元音字母且辅音数量 至少为 k 的子串总数。
         * helper(word, k + 1) 计算包含所有元音字母且辅音数量 至少为 k+1 的子串总数。
         * */
        return this.helper(word, k) - this.helper(word, k + 1);
    }

    private long helper(String word, int k) {
        Set<Character> vowels = Set.of('a', 'e', 'i', 'o', 'u');
        int len = word.length();
        //辅音数量
        int consonantCount = 0;
        long res = 0;
        Map<Character, Integer> occur = new HashMap<>();
        int j = 0;
        for (int i = 0; i < len; i++) {
            //统计元音和辅音数量
            while (j < len && (consonantCount < k || occur.size() < 5)) {
                char ch = word.charAt(j);
                if (vowels.contains(ch)) {
                    occur.put(ch, occur.getOrDefault(ch, 0) + 1);
                } else {
                    consonantCount++;
                }
                j++;
            }
            if (consonantCount >= k && occur.size() == 5) {
                res += len - j + 1;
            }
            //处理左边界值，下次循环再次使用
            char left = word.charAt(i);
            if (vowels.contains(left)) {
                occur.put(left, occur.getOrDefault(left, 0) - 1);
                if (occur.get(left) == 0) {
                    occur.remove(left);
                }
            } else {
                consonantCount--;
            }
        }
        return res;
    }


}
